﻿using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.IT;
using Coldairarrow.Entity.PB;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.PB
{
    public partial class PB_AreaSignInBusiness : BaseBusiness<PB_AreaSignIn>, IPB_AreaSignInBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        public PB_AreaSignInBusiness(IDbAccessor db, IOperator @operator)
            : base(db)
        {
            _operator = @operator;
        }

        #region 外部接口

        public async Task<PageResult<PB_AreaSignIn>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<PB_AreaSignIn>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<PB_AreaSignIn, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<PB_AreaSignIn> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(PB_AreaSignIn data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(PB_AreaSignIn data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }


        /// <summary>
        /// 库区签到
        /// </summary>
        /// <param name="QrCodeJson">签到二维码</param>
        /// <returns></returns>
        public async Task<List<LocalMaterialSignDTO>> UpAreaSignInAsync(string QrCodeJson)
        {
            if (QrCodeJson.IsNullOrEmpty())
            {
                throw new BusException("二维码不能为空");
            }
            else
            {
                //解析json
                AreaSignIn asdata = QrCodeJson.ToObject<AreaSignIn>();
                string RHeader = asdata.RHeader;
                if (RHeader == "35")
                {
                    //获取货架信息
                    List<string> racknames = new List<string>();
                    foreach (var item in asdata.RackNames)
                    {
                        racknames.Add(item);
                    }
                    List<PB_Rack> racklist = await Db.GetIQueryable<PB_Rack>().Where(x => x.AreaId == asdata.StorAreaId && racknames.Contains(x.Name)).ToListAsync();
                    //获取货位信息
                    List<string> rackids = new List<string>();
                    foreach (var item in racklist)
                    {
                        rackids.Add(item.Id);
                    }
                    List<PB_Location> localist = await Db.GetIQueryable<PB_Location>().Where(x => x.AreaId == asdata.StorAreaId && rackids.Contains(x.RackId)).ToListAsync();
                    //获取库存信息
                    List<string> locaids = new List<string>();
                    foreach (var item in localist)
                    {
                        locaids.Add(item.Id);
                    }
                    Expression<Func<IT_LocalMaterial, PB_Material, Base_Department, PB_Location, PB_StorArea, PB_Rack, LocalMaterialSignDTO>> selectdata = (a, b, c, d, e, f) => new LocalMaterialSignDTO
                    {
                        StorId = a.StorId,
                        StorName = c.Name,
                        LocalId = a.LocalId,
                        LocalName = e.Name + "/" + f.Name + "/" + d.Name,
                        MaterialId = a.MaterialId,
                        MaterialCode = b.Code,
                        MaterialName = b.Name,
                        MaterialSpec = b.Spec,
                        ScanNum = a.ScanNum
                    };
                    selectdata = selectdata.BuildExtendSelectExpre();
                    var qdata = from a in Db.GetIQueryable<IT_LocalMaterial>().AsExpandable()
                                join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                                from b in ab.DefaultIfEmpty()
                                join c in Db.GetIQueryable<Base_Department>() on a.StorId equals c.Id into ac
                                from c in ac.DefaultIfEmpty()
                                join d in Db.GetIQueryable<PB_Location>() on a.LocalId equals d.Id into ad
                                from d in ad.DefaultIfEmpty()
                                join e in Db.GetIQueryable<PB_StorArea>() on d.AreaId equals e.Id into de
                                from e in de.DefaultIfEmpty()
                                join f in Db.GetIQueryable<PB_Rack>() on d.RackId equals f.Id into df
                                from f in df.DefaultIfEmpty()
                                select @selectdata.Invoke(a, b, c, d, e, f);

                    List<LocalMaterialSignDTO> signlist = await qdata.Where(x => locaids.Contains(x.LocalId)).ToListAsync();

                    PB_AreaSignIn areasign = new PB_AreaSignIn();
                    areasign.Id = IdHelper.GetId();
                    areasign.DeptId = _operator.Property?.DepartmentId;
                    areasign.CreatorId = _operator.UserId;
                    areasign.CreatorRealName = _operator.Property?.RealName;
                    areasign.CreateTime = DateTime.Now;
                    areasign.Deleted = false;
                    areasign.Title = asdata.Title;
                    areasign.QrCodExplain = QrCodeJson;
                    areasign.Remarks = "";
                    areasign.StorAreaBalance = signlist.ToJson();
                    await Db.InsertAsync<PB_AreaSignIn>(areasign);
                    return signlist;
                }
                else
                {
                    throw new BusException("请扫描正确的二维码信息");
                }
            }
        }

        #endregion

        #region 私有成员

        #endregion
    }
}